# -*- coding: utf-8 -*-

"""
日志 django中间件
"""
import json

from django.conf import settings
from django.contrib.auth.models import AnonymousUser
from django.utils.deprecation import MiddlewareMixin

from apps.sys.models import OperLog
from core.request import *


class ApiLoggingMiddleware(MiddlewareMixin):
    """
    用于记录API访问日志中间件
    """

    def __init__(self, get_response=None):
        super().__init__(get_response)
        self.enable = getattr(settings, 'API_LOG_ENABLE', None) or False
        self.methods = getattr(settings, 'API_LOG_METHODS', None) or set()
        self.oper_log_id = None

    @classmethod
    def __handle_request(cls, request):
        request.ip = get_request_ip(request)
        request.data = get_request_data(request)
        request.path = get_request_path(request)

    def __process_view(self, request, view_func, view_args, view_kwargs):
        # 1、在OperLog中记录操作日志
        log = OperLog(module=get_verbose_name(view_func.cls.queryset))
        self.oper_log_id = log.id
        log.save()

    def __handle_response(self, request, response):
        # data,ip由PermissionInterfaceMiddleware中间件中添加的属性
        body = getattr(request, 'data', {})
        # 请求含有password则用*替换掉(暂时先用于所有接口的password请求参数)
        if isinstance(body, dict) and body.get('password', ''):
            body['password'] = '*' * len(body['password'])
        if not hasattr(response, 'data') or not isinstance(response.data, dict):
            response.data = {}
        try:
            if not response.data and response.content:
                content = json.loads(response.content.decode())
                response.data = content if isinstance(content, dict) else {}
        except Exception:
            return
        user = get_request_user(request)
        log_info = {
            'ip': getattr(request, 'ip', 'unknown'),
            'creator': user if not isinstance(user, AnonymousUser) else None,
            'dept_belong_id': getattr(request.user, 'dept_id', None),
            'method': request.method,
            'path': request.path,
            'body': body,
            'code': response.data.get('code'),
            'os': get_os(request),
            'browser': get_browser(request),
            'msg': request.session.get('request_msg'),
            'status': "0" if response.data.get('code') in [200, ] else "1",
            'result': {"code": response.data.get('code'), "msg": response.data.get('msg')},
        }
        oper_log, _ = OperLog.objects.update_or_create(
            defaults=log_info, id=self.oper_log_id)
        if not oper_log.module and settings.API_MODEL_MAP.get(request.path, None):
            oper_log.module = settings.API_MODEL_MAP[request.path]
            oper_log.save()

    # 在视图之前执行

    def process_request(self, request):
        self.__handle_request(request)

    # 在视图之前执行顺序执行
    def process_view(self, request, view_func, view_args, view_kwargs):
        if hasattr(view_func, 'cls') and hasattr(view_func.cls, 'queryset'):
            if self.enable:
                if self.methods == 'ALL' or request.method in self.methods:
                    self.__process_view(request, view_func,
                                        view_args, view_kwargs)
        return

    # 基于请求响应，在视图之后
    def process_response(self, request, response):
        """
        主要请求处理完之后记录
        :param request:
        :param response:
        :return:
        """
        if self.enable:
            if self.methods == 'ALL' or request.method in self.methods:
                self.__handle_response(request, response)
        return response
